package com.high.config;

import com.baomidou.mybatisplus.core.parser.ISqlParser;
import com.baomidou.mybatisplus.core.parser.ISqlParserFilter;
import com.baomidou.mybatisplus.core.parser.SqlParserHelper;
import com.baomidou.mybatisplus.extension.parsers.DynamicTableNameParser;
import com.baomidou.mybatisplus.extension.parsers.ITableNameHandler;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * @author zhaozhengshi
 * @version 1.0
 * @ClassName: MybatisPlusConfiguration
 * @Description:
 * @date: 2022/3/2 11:03
 * @since JDK 1.8
 */
@Configuration
public class MybatisPlusConfiguration {

    public static ThreadLocal<String> myTableName = new ThreadLocal<>();

    //    乐观锁插件
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }

    //    性能分析插件
    @Bean
    @Profile({"dev", "test"})// 在开发环境和测试环境开启性能分析，生产环境不开启
    public PerformanceInterceptor performanceInterceptor() {
        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        //  格式化sql
        performanceInterceptor.setFormat(true);
        //  超过5ms的sql都会打印
        performanceInterceptor.setMaxTime(5L);
        return performanceInterceptor;
    }

    //    分页插件,实现多租户,特定sql过滤
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        ArrayList<ISqlParser> sqlParsersList = new ArrayList<>();
//        实现多租户解析器
        /*TenantSqlParser tenantSqlParser = new TenantSqlParser();
        tenantSqlParser.setTenantHandler(new TenantHandler() {
            @Override
            public Expression getTenantId() {
//                租户读取到的配置信息或者session信息
                return new LongValue(1088248166370832385L);
            }

            @Override
            public String getTenantIdColumn() {
//                租户字段
                return "manager_id";
            }

            @Override
            public boolean doTableFilter(String tableName) {
//                不增加租户信息的表
//                if ("user".equals(tableName)) {
//                    return true;
//                }
                return false;
            }
        });
        sqlParsersList.add(tenantSqlParser);*/
//        动态表名实现
        DynamicTableNameParser dynamicTableNameParser = new DynamicTableNameParser();
        HashMap<String, ITableNameHandler> tableNameHandlerMap = new HashMap<>();
        tableNameHandlerMap.put("user", new ITableNameHandler() {
            @Override
            public String dynamicTableName(MetaObject metaObject, String sql, String tableName) {
                return myTableName.get();
            }
        });
        dynamicTableNameParser.setTableNameHandlerMap(tableNameHandlerMap);
        sqlParsersList.add(dynamicTableNameParser);

        paginationInterceptor.setSqlParserList(sqlParsersList);
//        多租户解析器，特定sql过滤,不添加租户信息或动态表名
        paginationInterceptor.setSqlParserFilter(new ISqlParserFilter() {
            @Override
            public boolean doFilter(MetaObject metaObject) {

                MappedStatement ms = SqlParserHelper.getMappedStatement(metaObject);
                if("com.high.dao.UserMapper.selectById".equals(ms.getId())){
                    return true;
                }
                return false;
            }
        });
        return paginationInterceptor;
    }
}
